import { EventSystem } from "../../../../../Core/Module/EventSystem/EventSystem";
import { Log } from "../../../../../Core/Module/Log/Log";
import { ObjectSystemAttribute, FriendOf, ExpandOf, GetCustomAttributes, GetTypeOf } from "../../../../../Decorator/Decorator";
import { PanelId } from "../../../../ModelView/Client/Demo/FUIAutoGen/PanelId";
import { FUIEventAttribute } from "../../../../ModelView/Client/Plugins/FairyGUI/FUIEventAttribute";
import { FUIEventComponent, PanelInfo } from "../../../../ModelView/Client/Plugins/FairyGUI/FUIEventComponent";
import { IFUIEventHandler } from "../../../../ModelView/Client/Plugins/FairyGUI/IFUIEventHandler";
import { LoadSystem } from "../../../../../Core/Module/EventSystem/ILoadSystem";
import { AwakeSystem } from "../../../../../Core/Module/EventSystem/IAwakeSystem";
import { DestroySystem } from "../../../../../Core/Module/EventSystem/IDestroySystem";

/**
 * 使用 Expand 扩展方法
 * 
 * 必须作出以下申明，才能调用对象的扩展方法
 */
declare module "../../../../ModelView/Client/Plugins/FairyGUI/FUIEventComponent" {

    interface FUIEventComponent {
        Load();
        GetUIEventHandler(panelId: PanelId): IFUIEventHandler;
        GetPanelInfo(panelId: PanelId): PanelInfo;
    }

}

@ExpandOf(FUIEventComponent)
export class FUIEventComponentSystem {

    private static Load(self: FUIEventComponent) {
        self.UIEventHandlers.Clear();
        self.PanelIdInfoDict.Clear();
        self.PanelTypeInfoDict.Clear();

        let types = EventSystem.Instance.GetTypes(GetTypeOf(FUIEventAttribute));
        for (let type in types) {
            let clazz = types[type];
            let ifuiHandler = new clazz() as IFUIEventHandler;
            if (ifuiHandler == null) {
                Log.Error(`ui handle ${clazz.Name} 需要继承 IFUIEventHandler`);
                continue;
            }
            let attrs = GetCustomAttributes(clazz);
            let attr = attrs[0] as FUIEventAttribute;
            self.UIEventHandlers.Add(attr.PanelId, ifuiHandler);
            self.PanelIdInfoDict.Add(attr.PanelId, attr.PanelInfo);
            self.PanelTypeInfoDict.Add(attr.PanelId.toString(), attr.PanelInfo);
        }
    }

    private static GetUIEventHandler(self: FUIEventComponent, panelId: PanelId): IFUIEventHandler {
        let handler = self.UIEventHandlers.TryGetValue(panelId);
        if (handler) {
            return handler;
        }
        Log.Error(`panelId : ${panelId} is not have any uiEvent`);
        return null;
    }

    private static GetPanelInfo(self: FUIEventComponent, panelId: PanelId): PanelInfo {
        let panelInfo = self.PanelIdInfoDict.TryGetValue(panelId);
        if (panelInfo) {
            return panelInfo;
        }
        Log.Error(`panelId : ${panelId} is not have any panelInfo`);
        return new PanelInfo();
    }

}

@FriendOf(FUIEventComponent)
@ObjectSystemAttribute()
export class FUIEventComponentLoadSystem extends LoadSystem<FUIEventComponent> {

    Load(self: FUIEventComponent): void {
        FUIEventComponent.Instance = self;
        self.Load();
    }

}

@FriendOf(FUIEventComponent)
@ObjectSystemAttribute()
export class FUIEventComponentAwakeSystem extends AwakeSystem<FUIEventComponent> {

    Awake(self: FUIEventComponent): void {
        FUIEventComponent.Instance = self;
        self.Load();
    }

}

@FriendOf(FUIEventComponent)
@ObjectSystemAttribute()
export class FUIEventComponentDestroySystem extends DestroySystem<FUIEventComponent> {

    Destroy(self: FUIEventComponent): void {
        self.UIEventHandlers.Clear();
        self.PanelIdInfoDict.Clear();
        self.PanelTypeInfoDict.Clear();
        self.isClicked = false;
        FUIEventComponent.Instance = null;
    }

}